﻿using Cofe.Core.Property;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core.Utils;

namespace Cofe.Core.Implements
{
    public class PropertyDefinitionBase : IPropertyDefinitions
    {
        public PropertyDefinitionBase(Type enumType, Func<object, bool> filterFunc = null, int beginId = -1, int endId = -1)
        {
            Category = enumType;

            if (beginId != -1 && endId != -1)
            {
                BeginId = beginId;
                EndId = endId;
            }
            else
            {
                var propIdAttb = AttributeUtils<PropertyIdAttribute>.GetCustomAttributes(Category).FirstOrDefault();
                //var propIdAttb = Category.GetCustomAttributes(typeof(PropertyIdAttribute), false).FirstOrDefault();
                if (propIdAttb != null)
                {
                    BeginId = (propIdAttb as PropertyIdAttribute).BeginPropertyId;
                    EndId = (propIdAttb as PropertyIdAttribute).EndPropertyId;
                }
            }

            if (filterFunc == null)
                filterFunc = (p) => true;
            foreach (var value in Enum.GetValues(enumType))
                if (filterFunc(value))
                    _definitions.Add(value);
        }

        private List<object> _definitions = new List<object>();
        private IPropertyExpressionDefinitions _expressions = null;


        public Type Category { get; private set; }
        

        public int BeginId { get; private set; }
        public int EndId{ get; private set; }

  
        public IPropertyExpressionDefinitions Expressions { get { 
            return _expressions ?? (_expressions = new PropertyExpressionDefinitionBase(Category)); }
            protected set { _expressions = value; }
        }

        public IEnumerable<object> GetSupportedProperties()
        {
            return _definitions;
        }

                
        

        public override string ToString()
        {
            return String.Format("Definition: {0} with {1} items ({2}-{3})", Category, _definitions.Count, BeginId, EndId);
        }       
    }

    public class PropertyDefinitionBase<T> : PropertyDefinitionBase
    {
        public PropertyDefinitionBase(Func<object, bool> filterFunc = null)
            : base(typeof(T), filterFunc)
        {
        }

        public PropertyDefinitionBase(params object[] supportedProperties)
            : base(typeof(T), (p) => supportedProperties.Contains(p))
        {
        }

    }

   
}
